package com.thesis.component;

import com.alibaba.fastjson.JSON;
import com.thesis.response.Result;
import com.thesis.utils.ApplicationContexts;
import com.thesis.utils.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.nio.charset.StandardCharsets;

@Slf4j
@Component
public class LogInInterceptor implements HandlerInterceptor {

    @Resource
    private JwtUtil jwtUtil;
    /**
     * 访问控制器方法前执行--->也就是controller方法执行之前
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) throws Exception {
        HttpSession session = request.getSession();
        response.setCharacterEncoding(StandardCharsets.UTF_8.displayName());
        String token = (String) session.getAttribute("userId");
        if(!StringUtils.hasText(token)){
            log.error("用户未登录，不可以访问，请先登录");
            String requestURI = request.getRequestURI();
            log.error("被拦截的请求路径是{}",requestURI);
            response.getWriter().write(JSON.toJSONString(Result.error("未登录，请先登录",403)));
            //拦截请求
            return false;
        }
        //解析token
        String userId = jwtUtil.getToken2(token);
        //将用户信息id存入到当前线程中去
        assert userId != null;
        ApplicationContexts.setThreadLocal(userId);
        log.info("经过拦截器,已经将当前登录的用户id存入了ThreadLocal中");
        return true;
    }

    /**
     * 访问控制器方法之后执行--->也就是controller方法执行之后
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, ModelAndView modelAndView) throws Exception {
        HandlerInterceptor.super.postHandle(request,response,handler,modelAndView);
    }
    /**
     * 方法执行完成后执行--->一般用于释放资源
     * @param request
     * @param response
     * @param handler
     * @throws Exception
     */
    @Override
    public void afterCompletion(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, Exception ex) throws Exception {
        log.info("经过拦截器，已经清除ThreadLocal中的用户信息");
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
        //释放资源，防止oom
        ApplicationContexts.removeThreadLocal();
    }
}
